/*
 * Misc Utilities.
 * $Rev: 149 $
 */

#include <stdbool.h>   /* bool */
#include <stdlib.h>    /* calloc */
#include <sys/types.h> /* stat */
#include <sys/stat.h>  /* stat */
#include <unistd.h>    /* stat */
#include <assert.h>    /* assert */
#include <string.h>    /* strlen, strdup */
#include "utils.h"

bool path_is_file(const char *a_path) {
    bool res = false;
    int stat_res = 0;
    struct stat buf;

/* PRE */assert(valid_path_name(a_path));

    stat_res = stat(a_path, &buf);
    if (stat_res == 0) {
        res = S_ISREG(buf.st_mode);
    }

    return res;
}

bool path_is_directory(const char *a_path) {
    bool res = false;
    int stat_res = 0;
    struct stat buf;

/* PRE */assert(valid_path_name(a_path));

    stat_res = stat(a_path, &buf);
    if (stat_res == 0) {
        res = S_ISDIR(buf.st_mode);
    }

    return res;
}

off_t path_size(const char *a_path) {
    off_t res = 0;
    int stat_res = 0;
    struct stat buf;

/* PRE */assert(valid_path_name(a_path));
/* PRE */assert(path_is_file(a_path));

    stat_res = stat(a_path, &buf);
    if (stat_res == 0) {
        res = buf.st_size; /* total size, in bytes */
    }

    return res;
}

bool valid_path_name(const char *a_path) {
    return (a_path != NULL); /* && a_path has '\0' as terminator */
}

char *path_join(const char *p, const char *q) {
    char *res = NULL;

/* PRE */assert(valid_path_name(p));
/* PRE */assert(valid_path_name(q));

    debug("utils.c: path_join: p -> %s, q -> %s\n", p, q);

    /* 1 extra for DIR_SEPARATOR and 1 extra for terminating \0 */
    res = calloc(strlen(p) + 1 + strlen(q) + 1, sizeof(char));
    if (res != NULL) {
        res = strcat(res, p);
        res = strcat(res, DIR_SEPARATOR);
        res = strcat(res, q);
    }

    debug("utils.c: path_join: result -> %s\n", res);
    return res;
}
